#ifndef CQ_TASK_QUEUE_H
#define CQ_TASK_QUEUE_H

#include "CQ_defines.h"
#include "CQ_task.h"

#include <list>
#include <condition_variable>
#include <mutex>

DEFINE_NAMESPACE_CQ_BEGIN

template <typename T>
class CQQueue
{
	friend class CQLooper;
public:

	void enqueue(const T& t_)
	{
		std::unique_lock<std::mutex> _lock(m_mutex);
		m_queue.push_back(t_);
		m_cv.notify_all();
	}

	bool dequeue(T& t_, int ms_ = -1)
	{
		bool _re = false;
		std::unique_lock<std::mutex> _lock(m_mutex);
		if (m_queue.empty()) {
			if (ms_ < 0) {
				m_cv.wait(_lock);
			}
			else {
				m_cv.wait_until(_lock, std::chrono::system_clock::now() + std::chrono::milliseconds(ms_));
			}
		}
		else {
			t_ = m_queue.front();
			m_queue.pop_front();
			_re = true;
		}
		return _re;
	}

private:
	std::condition_variable m_cv;
	std::mutex m_mutex;
	std::list<T> m_queue;
};

typedef CQQueue<CQTaskBase*> CQTaskQueue;

DEFINE_NAMESPACE_CQ_END

#endif // CQ_TASK_QUEUE_H
